package br.com.freelancer.util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * Classe utilitária para tratamentos genéricos de datas
 * 
 * @author Walter Fontes
 *
 */
public class DataHelper {


	//Construtor privado. Os métodos devem ser estáticos
	private DataHelper() {}

	/**
	 * Obtém objeto date no último milissegundo do dia passado
	 * por parâmetro
	 * 
	 * @param data
	 * @return
	 */
	public static Date obtemDataFinal(Date data) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(data);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 99);
		return calendar.getTime();
	}

	/**
	 * Obtém objeto date no último milissegundo do dia passado
	 * por parâmetro
	 * 
	 * @param data
	 * @return
	 */
	public static Date obtemDataFinal(Date data, int dias) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(data);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 99);
		return obtemDataEm(calendar.getTime(), dias);
	}

	/**
	 * Obtém objeto date no primeiro milissegundo do dia passado
	 * por parâmetro
	 * 
	 * @param data
	 * @return
	 */
	public static Date obtemDataInicial(Date data) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(data);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * Obtém objeto date no primeiro milissegundo do dia passado
	 * por parâmetro
	 * 
	 * @param data
	 * @return
	 */
	public static Date obtemDataInicial(Date data, int dias) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(data);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return obtemDataEm(calendar.getTime(), dias);
	}

	/**
	 * Obtém objeto date com o primeiro dia
	 * por parâmetro
	 * 
	 * @param mesAno
	 * @param pattern
	 * @return
	 * @throws ParseException 
	 */
	public static Date obtemDataInicial(String data, String pattern) throws ParseException {
		if (data == null)
			return null;
		if (pattern == null) {
			pattern = "dd/MM/yyyy";
		}
		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(sdf.parse(data));
		return obtemDataInicial(calendar.getTime());
	}

	/**
	 * Obtém objeto date com o último dia 
	 * por parâmetro
	 * 
	 * @param mesAno
	 * @return
	 */
	public static Date obtemDataFinal(String data, String pattern) throws ParseException {
		if (data == null)
			return null;
		if (pattern == null) {
			pattern = "dd/MM/yyyy";
		}
		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(sdf.parse(data));
		return obtemDataFinal(calendar.getTime());
	}

	/**
	 * Obtém objeto date com o primeiro dia do mes/ano passado (MM/yyyy)
	 * por parâmetro
	 * 
	 * @param mesAno
	 * @return
	 */
	public static Date obtemDataInicial(String mesAno) {

		if (mesAno == null)
			return null;

		String[] _mesAno = mesAno.split("/");

		int dia = 1;
		int mes = Integer.parseInt(_mesAno[0]) - 1;
		int ano = Integer.parseInt(_mesAno[1]);

		GregorianCalendar calendar = new GregorianCalendar();
		calendar.set(Calendar.DAY_OF_MONTH, dia);
		calendar.set(Calendar.MONTH, 		mes);
		calendar.set(Calendar.YEAR, 		ano);

		return obtemDataInicial(calendar.getTime());
	}

	/**
	 * Obtém objeto date com o último dia do mes/ano passado (MM/yyyy)
	 * por parâmetro
	 * 
	 * @param mesAno
	 * @return
	 */
	public static Date obtemDataFinal(String mesAno) {

		if (mesAno == null)
			return null;

		Date dataInicial = obtemDataInicial(mesAno);

		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(dataInicial);
		calendar.add(Calendar.MONTH, 		1);
		calendar.add(Calendar.DAY_OF_MONTH, -1);

		return obtemDataFinal(calendar.getTime());
	}
	public static Date obtemDataFinal(Long dt) {

		if (dt == null)
			return null;

		Date dataInicial = obtemDataInicial(dt);

		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(dataInicial);
		calendar.add(Calendar.MONTH, 		1);
		calendar.add(Calendar.DAY_OF_MONTH, -1);

		return obtemDataFinal(calendar.getTime());
	}
	
	public static Date obtemDataInicial(Long dt) {

		if (dt == null)
			return null;

		Date dataInicial = new Date(dt);

		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(dataInicial);
		calendar.set(Calendar.DAY_OF_MONTH, 1);

		return obtemDataFinal(calendar.getTime());
	}
	
		
	
	/**
	 * Calcula data para D+ ou D-.
	 * 
	 * @param data Data
	 * @param dias Numero de dias em D+ ou D-
	 * @return
	 */
	public static Date obtemDataEm(Date data, int dias) {
		if (data != null) {
			GregorianCalendar calendar = new GregorianCalendar();
			calendar.setTime(data);
			if (dias != 0) {
				calendar.add(Calendar.DAY_OF_MONTH, dias);
			}
			return calendar.getTime();
		}
		return null;
	}


	/**
	 * Obtém data por extenso
	 * 
	 * @param data
	 * @return
	 */
	public static String obtemDataPorExtenso(Date data) {  

		String mesf = null;  
		String retorno = null;  

		Calendar calendar = new GregorianCalendar();  
		calendar.setTime(data);  

		int mes 	= calendar.get(Calendar.MONTH);  
		int dia 	= calendar.get(Calendar.DAY_OF_MONTH);  
		int ano 	= calendar.get(Calendar.YEAR);  

		// m�s  
		switch(mes) {  
		case 0:  mesf = "Janeiro"; 		break;
		case 1:  mesf = "Fevereiro";	break;  
		case 2:  mesf = "Março";  		break;
		case 3:  mesf = "Abril";  		break;
		case 4:  mesf = "Maio";  		break;
		case 5:  mesf = "Junho";  		break;
		case 6:  mesf = "Julho";  		break;
		case 7:  mesf = "Agosto";  		break;
		case 8:  mesf = "Setembro";  	break;
		case 9:  mesf = "Outubro";		break;  		
		case 10: mesf = "Novembro";  	break;
		case 11: mesf = "Dezembro";		break;  
		}  
		retorno = dia+" de "+mesf+" de "+ano;  
		return retorno;  
	}


	/**
	 * Obtém o ano de uma data
	 * 
	 * @param data
	 * @return
	 */
	public static int obtemAnoData(Date data) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(data);
		return calendar.get(Calendar.YEAR);
	}


	/**
	 * Obtém o ano de uma data
	 * 
	 * @param data
	 * @return
	 */
	public static String obtemDiaJuliano(Date data) {
		DateFormat df = new SimpleDateFormat ("D");  
		return (df.format (data));  
		}
	/**
	 * Obtém diferença entre horas
	 * 
	 * @param horaIncial (HH:mm)
	 * @param horaFinal (HH:mm)
	 * @return
	 */
	public static String obtemDiferencaHoras(String horaIncialFormatada, String horaFinalFormatada) throws Exception {

		String diferencaHorasStr = null;

		try {
			int totalMinutosInicial = (Integer.parseInt(horaIncialFormatada.split(":")[0]) * 60) + Integer.parseInt(horaIncialFormatada.split(":")[1]);
			int totalMinutosFinal   = (Integer.parseInt(horaFinalFormatada.split(":")[0])  * 60) + Integer.parseInt(horaFinalFormatada.split(":")[1]);

			int diferencaMinutos = totalMinutosFinal - totalMinutosInicial;
			if (diferencaMinutos < 0) {
				return "00:00";
			}

			int diferencaHoras = diferencaMinutos / 60;
			diferencaMinutos = diferencaMinutos % 60;  

			diferencaHorasStr = ((diferencaHoras   < 10) ? "0" + diferencaHoras:   String.valueOf(diferencaHoras))      + ":" +
					((diferencaMinutos < 10) ? "0" + diferencaMinutos: String.valueOf(diferencaMinutos));

		} catch (Exception e) {
			throw e;
		}
		return diferencaHorasStr;
	}


	/**
	 * Obtém diferente entre a data passada por parâmetro e data atual em anos (idade) 
	 * 
	 * @param dataInicialFormatada (dd/MM/yyyy)
	 * @return
	 */
	public static int obtemDiferencaAnos(String dataInicialFormatada) throws Exception {

		int diferencaAnos = 0;

		try {
			Calendar dataInicial = new GregorianCalendar();
			dataInicial.setTime(new SimpleDateFormat("dd/MM/yyyy").parse(dataInicialFormatada));

			Calendar dataAtual = new GregorianCalendar();

			int anoInicial = dataInicial.get(Calendar.YEAR);
			int mesInicial = dataInicial.get(Calendar.MONTH);
			int diaInicial = dataInicial.get(Calendar.DATE);

			int anoAtual = dataAtual.get(Calendar.YEAR);
			int mesAtual = dataAtual.get(Calendar.MONTH);
			int diaAtual = dataAtual.get(Calendar.DATE);

			diferencaAnos = anoAtual - anoInicial;

			if (mesAtual < mesInicial) {  
				diferencaAnos --;

			} else if (mesAtual == mesInicial) {
				if (diaAtual < diaInicial) {
					diferencaAnos --;
				}
			}

		} catch (Exception e) {
			throw e;
		}
		return diferencaAnos;
	}    


	public static Date getDate(String data) throws ParseException{
		return new SimpleDateFormat("dd/MM/yyyy").parse(data);
	}
	public static Date getDate(Timestamp data) throws ParseException{
		if (ObjectHelper.isNotNull(data)) {
			return new Date(data.getTime());
		}else{
			return null;
		}
	}	
	public static boolean isValidDate(String inDate) {
		if (inDate == null) {
			return false;
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
		if (inDate.trim().length() != dateFormat.toPattern().length()) {
			return false;
		}
		dateFormat.setLenient(false);
		try {
			dateFormat.parse(inDate.trim());
		} catch (ParseException pe) {
			return false;
		}
		return true;
	}

	/**
	 * Formatar data no formato dd/MM/yyyy
	 * @param data
	 * @return
	 */
	public static String formataData(Date data) {
		if(ObjectHelper.isNotNull(data)){
			return new SimpleDateFormat("dd/MM/yyyy").format(data);
		}else{
			return "";
		}
	}
	/**
	 * Formatar data no formato dd/MM/yyyy
	 * @param data
	 * @return
	 */
	public static String formataDataDDMMYY(Date data) {
		if(ObjectHelper.isNotNull(data)){
			return new SimpleDateFormat("dd/MM/yy").format(data);
		}else{
			return "";
		}
	}
	/**
	 * Formatar data no formato dd/MM
	 * @param data
	 * @return
	 */
	public static String formataDiaEMes(Date data) {
		if(ObjectHelper.isNotNull(data)){
			return new SimpleDateFormat("dd/MM").format(data);
		}else{
			return "";
		}
	}
	/**
	 * Formatar data no formato dd/MM/yyyy HH:mm
	 * @param data
	 * @return
	 */
	public static String formataDataHora(Date data) {
		if(ObjectHelper.isNotNull(data)){
			return new SimpleDateFormat("dd/MM/yyyy HH:mm").format(data);
		}else{
			return "";
		}
	}	
	public static String formataDataHoraSegundo(Date data) {
		if(ObjectHelper.isNotNull(data)){
			return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(data);
		}else{
			return "";
		}
	}	
	public static Date getDataHoraSegundo(String data) throws ParseException {
		if(ObjectHelper.isNotNull(data)){
			return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").parse(data);
		}else{
			return null;
		}
	}
	
	/**
	 * Formatar data no formato dd/MM/yyyy HH:mm
	 * @param data
	 * @return
	 */
	public static String formataDiaHora(Date data) {
		if(ObjectHelper.isNotNull(data)){
			return new SimpleDateFormat("dd '/' HH:mm").format(data);
		}else{
			return "";
		}
	}
	
	/**
	 * Formatar data no formato dd/MM/yyyy HH:mm
	 * @param data
	 * @return
	 */
	public static String formataDataHoraXML(Date data) {
		if(ObjectHelper.isNotNull(data)){
			String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(data);
			return format.replaceFirst(" ", "T");
		}else{
			return "";
		}
	}	
	public static Date getDateXML(String data) throws ParseException{
		data=data.replaceFirst("T", " ");
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(data);
	}
	public static Date getDataXML(String data) throws ParseException{

		return new SimpleDateFormat("ddMMyyyy").parse(data);
	}

	/**
	 * Obtem a data em D+ pu D-.
	 * 
	 * @param data
	 * @param dias Numero de dias.
	 * @return
	 * @throws ParseException
	 */
	public static Date getDataXML(String data, int dias) throws ParseException{

		return obtemDataEm(getDataXML(data), dias);
	}


	public static Date getDateYYYYMMDD(String data) throws ParseException{
		return new SimpleDateFormat("yyyy-MM-dd").parse(data);
	}


	/**
	 * Verifica se a data é válida
	 * @param data
	 * @return
	 */
	public static boolean dataValida(String data) {
		if(ObjectHelper.isEmpty(data)){
			return false;
		}else{
			if(data.replaceAll("_", "").length() != 10){
				return false;
			}
		}
		try {

			return isValidDate(data);
		} catch (Exception e) {
			return false;
		}
	}


	/**
	 * Verifica se a data (mm/yyyy) é válida
	 * @param mesAno
	 * @return
	 */
	public static boolean mesAnoValido(String mesAno) {
		try {
			getDate("01/" + mesAno);
		} catch (Exception e) {
			return false;
		}
		return true;
	}


	/**
	 * Verifica se a data (mm/yyyy) é válida
	 * @param mesAno
	 * @return
	 */
	public static Date getData(String mesAno, int dia) {
		try {

			String diaStr = String.valueOf(dia);
			if (dia < 10) {
				diaStr = " " + diaStr;
			}
			return getDate(diaStr + "/" + mesAno);
		} catch (Exception e) {
			return null;
		}
	}	


	/**
	 * formata hora
	 * @param data
	 * @return
	 */
	public static String formataHora(Date data) {
		if(ObjectHelper.isNotNull(data)){
			return new SimpleDateFormat("HH:mm:ss").format(data);
		}else{
			return "";
		}
	}

	/**
	 * Obtém diferente entre dias 
	 * 
	 * @param dataInicial
	 * @param dataFinal
	 * @return
	 */
	public static int obtemDiferencaDias(Timestamp dataInicial, Date dataFinal) throws Exception {
		return obtemDiferencaDias(getDate(dataInicial), dataFinal);
	}	

	public static int obtemDiaHoje(){
		GregorianCalendar calendar = new GregorianCalendar();
		return calendar.get(Calendar.DAY_OF_MONTH);
	}
	public static int obtemDia(Date d){
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(d);
		return calendar.get(Calendar.DAY_OF_MONTH);
	}



	/**
	 * Obtém diferente entre dias 
	 * 
	 * @param dataInicial
	 * @param dataFinal
	 * @return
	 */
	public static int obtemDiferencaDias(Date dataInicial, Date dataFinal) throws Exception {

		int diferencaDias = 0;

		try {

			dataInicial = obtemDataInicial(dataInicial);
			dataFinal = obtemDataInicial(dataFinal);

			if (dataInicial.before(dataFinal)) {
				Calendar cDataInicial = new GregorianCalendar();
				cDataInicial.setTime(dataInicial);

				while (cDataInicial.getTime().before(dataFinal)) {
					diferencaDias++;
					cDataInicial.add(Calendar.DATE, 1);
				}
				return diferencaDias; 

			} else if (dataInicial.after(dataFinal)) {
				Calendar cDataFinal = new GregorianCalendar();
				cDataFinal.setTime(dataFinal);

				while (dataInicial.after(cDataFinal.getTime())) {
					diferencaDias++;
					cDataFinal.add(Calendar.DATE, 1);
				}
				return diferencaDias * -1; 

			} else {
				return diferencaDias;
			}

		} catch (Exception e) {
			throw e;
		}
	}

	public static Date hoje() throws ParseException {
		return getDate(formataData(new Date()));
	}
	/**
	 * Método respons�vel em criar um timestamp (horas e milesegundos).
	 * 
	 * @return Timestamp
	 * @throws ParseException
	 * 
	 * @author and
	 */
	public static Timestamp hojeEmMilesegundos() {
		Calendar dataHoje = new GregorianCalendar();
		return new Timestamp(dataHoje.getTimeInMillis());
	} 


	/**
	 * Verifica se a data é a data atual
	 * 
	 * @param date
	 * @return
	 * @throws Exception
	 */
	public static boolean dataAtual(Date date) throws Exception {
		return (obtemDiferencaDias(date, new Date()) == 0);
	}

	public static boolean between(Date dataInicial, Date dataFinal,
			Date data) {

		if(data.before(dataFinal) && dataFinal.after(dataInicial)) return true;

		return false;

	}


	/**
	 * Subtrai um dia da data atual
	 * @return 
	 * @throws ParseException 
	 */
	public static String subtraiData() throws ParseException{
		String data = null;
		Calendar subtraiData = Calendar.getInstance();
		subtraiData.add(Calendar.DAY_OF_WEEK, -1);		  

		return formataData(subtraiData.getTime());

	}

	public static String formataDataXML(Date data) {
		if(ObjectHelper.isNotNull(data)){
			return new SimpleDateFormat("ddMMyyyy").format(data);
		}else{
			return "";
		}
	}
	public static String formataDataYYYMMDD(String data) {
		if(ObjectHelper.isNotNull(data)){
			return new SimpleDateFormat("yyyy-MM-dd").format(data);
		}else{
			return "";
		}
	}
	public static String formataDiaMes(Date data) {

		Calendar calendar = Calendar.getInstance();

		calendar.setTime(data);

		if (ObjectHelper.isNotNull(data)) {
			return calendar.get(Calendar.DAY_OF_MONTH) + " de " + getMes(calendar.get(Calendar.MONTH));
		} else {
			return "";
		}
	}

	
	public static String getMesAbrevDia() {
		Calendar calendar = Calendar.getInstance();
		String mes = getMesAbrev(calendar.get(Calendar.MONTH));
		String dia = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
		return (dia.length()==1?"0":"") + dia + "/"+ mes;
	}
	
	public static String getMesAno() {
		Calendar calendar = Calendar.getInstance();
		String mes = getMes(calendar.get(Calendar.MONTH));
		String ano = String.valueOf(calendar.get(Calendar.YEAR));
		return mes + " " + ano;
	}
	
	private static String getMes(int numMes) {

		String mes = "";

		switch (numMes) {
		case 0:

			mes = "Janeiro";

			break;

		case 1:

			mes = "Fevereiro";

			break;
		case 2:

			mes = "Março";

			break;

		case 3:

			mes = "Abril";

			break;
		case 4:

			mes = "Maio";

			break;
		case 5:

			mes = "Junho";

			break;
		case 6:

			mes = "Julho";

			break;
		case 7:

			mes = "Agosto";

			break;
		case 8:

			mes = "Setembro";

			break;
		case 9:

			mes = "Outubro";

			break;
		case 10:

			mes = "Novembro";

			break;
		case 11:

			mes = "Dezembro";

			break;

		}

		return mes;

	}

	
	private static String getMesAbrev(int numMes) {

		String mes = "";

		switch (numMes) {
		case 0: mes = "Jan";
			break;
		case 1: mes = "Fev";
			break;
		case 2: mes = "Mar";
			break;
		case 3: mes = "Abr";
			break;
		case 4: mes = "Mai";
			break;
		case 5: mes = "Jun";
			break;
		case 6: mes = "Jul";
			break;
		case 7: mes = "Ago";
			break;
		case 8: mes = "Set";
			break;
		case 9: mes = "Out";
			break;
		case 10: mes = "Nov";
			break;
		case 11: mes = "Dez";
			break;
		}
		return mes;
	}
	
	public static Date getAnoAtualInicio() {

		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.HOUR_OF_DAY, 0);
		instance.set(Calendar.MINUTE, 0);
		instance.set(Calendar.SECOND, 0);
		instance.set(Calendar.MILLISECOND, 0);

		instance.set(Calendar.DAY_OF_MONTH, 1);
		instance.set(Calendar.MONTH, Calendar.JANUARY);

		return instance.getTime() ;
	}

	public static Date getAnoAtualFim() {	

		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.DAY_OF_MONTH, 31);
		instance.set(Calendar.MONTH, Calendar.DECEMBER);

		instance.set(Calendar.HOUR_OF_DAY, 23);
		instance.set(Calendar.MINUTE, 59);
		instance.set(Calendar.SECOND, 59);
		instance.set(Calendar.MILLISECOND, 99);


		return instance.getTime() ;
	}

	public static Date getAnoPassadoInicio() {	
		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.HOUR_OF_DAY, 0);
		instance.set(Calendar.MINUTE, 0);
		instance.set(Calendar.SECOND, 0);
		instance.set(Calendar.MILLISECOND, 0);

		instance.set(Calendar.DAY_OF_MONTH, 1);
		instance.set(Calendar.MONTH, Calendar.JANUARY);
		instance.set(Calendar.YEAR, instance.get(Calendar.YEAR) - 1);

		return instance.getTime() ;
	}

	public static Date getAnoPassadoFim() {	
		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.DAY_OF_MONTH, 31);
		instance.set(Calendar.MONTH, Calendar.DECEMBER);

		instance.set(Calendar.HOUR_OF_DAY, 23);
		instance.set(Calendar.MINUTE, 59);
		instance.set(Calendar.SECOND, 59);
		instance.set(Calendar.MILLISECOND, 99);
		instance.set(Calendar.YEAR, instance.get(Calendar.YEAR) - 1);

		return instance.getTime() ;
	}

	public static Date getMesAtualInicio() {	
		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.HOUR_OF_DAY, 0);
		instance.set(Calendar.MINUTE, 0);
		instance.set(Calendar.SECOND, 0);
		instance.set(Calendar.MILLISECOND, 0);

		instance.set(Calendar.DAY_OF_MONTH, 1);

		return instance.getTime() ;
	}

	public static Date getMesAtualFim() {	
		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.DAY_OF_MONTH, -1);
		instance.set(Calendar.MONTH, instance.get(Calendar.MONTH) + 1);


		instance.set(Calendar.HOUR_OF_DAY, 23);
		instance.set(Calendar.MINUTE, 59);
		instance.set(Calendar.SECOND, 59);
		instance.set(Calendar.MILLISECOND, 99);

		return instance.getTime() ;
	}

	public static Date getMesPassadoInicio() {	
		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.HOUR_OF_DAY, 0);
		instance.set(Calendar.MINUTE, 0);
		instance.set(Calendar.SECOND, 0);
		instance.set(Calendar.MILLISECOND, 0);

		instance.set(Calendar.DAY_OF_MONTH, 1);
		instance.set(Calendar.MONTH, instance.get(Calendar.MONTH) - 1);

		return instance.getTime() ;
	}

	public static Date getMesPassadoFim() {	
		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.DAY_OF_MONTH, -1);

		instance.set(Calendar.HOUR_OF_DAY, 23);
		instance.set(Calendar.MINUTE, 59);
		instance.set(Calendar.SECOND, 59);
		instance.set(Calendar.MILLISECOND, 99);

		return instance.getTime() ;
	}

	public static Date getOntemInicio() {	
		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.DAY_OF_MONTH, instance.get(Calendar.DAY_OF_MONTH)-1);
		instance.set(Calendar.HOUR_OF_DAY, 0);
		instance.set(Calendar.MINUTE, 0);
		instance.set(Calendar.SECOND, 0);
		instance.set(Calendar.MILLISECOND, 0);


		return instance.getTime() ;
	}

	public static Date getOntemFim() {	
		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.DAY_OF_MONTH, instance.get(Calendar.DAY_OF_MONTH)-1);
		instance.set(Calendar.HOUR_OF_DAY, 23);
		instance.set(Calendar.MINUTE, 59);
		instance.set(Calendar.SECOND, 59);
		instance.set(Calendar.MILLISECOND, 99);


		return instance.getTime() ;
	}

	public static Date obtemDataMinutoInicial(Integer qtdeMinutoTimestamp) {	
		Calendar instance = Calendar.getInstance();
		instance.set(Calendar.MINUTE, instance.get(Calendar.MINUTE)-qtdeMinutoTimestamp);
		instance.set(Calendar.SECOND, 0);
		instance.set(Calendar.MILLISECOND, 0);


		return instance.getTime() ;
	}

	public static Date obtemDataMinutoIFinal(Integer qtdeMinutoTimestamp) {	
		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.SECOND, 59);
		instance.set(Calendar.MILLISECOND, 99);


		return instance.getTime() ;
	}

	public static Date getSemanalInicio() {	
		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.HOUR_OF_DAY, 0);
		instance.set(Calendar.MINUTE, 0);
		instance.set(Calendar.SECOND, 0);
		instance.set(Calendar.MILLISECOND, 0);

		instance.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

		return instance.getTime() ;
	}
	public static Date getSemanalFim() {	
		Calendar instance = Calendar.getInstance();


		instance.set(Calendar.HOUR_OF_DAY, 23);
		instance.set(Calendar.MINUTE, 59);
		instance.set(Calendar.SECOND, 59);
		instance.set(Calendar.MILLISECOND, 99);

		return instance.getTime() ;

	}



	public static Date getSemanaPassadaInicio() {	
		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.HOUR_OF_DAY, 0);
		instance.set(Calendar.MINUTE, 0);
		instance.set(Calendar.SECOND, 0);
		instance.set(Calendar.MILLISECOND, 0);

		instance.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

		instance.set(Calendar.DAY_OF_MONTH, instance.get(Calendar.DAY_OF_MONTH)-7);

		return instance.getTime() ;
	}

	public static Date getSemanaPassadaFim() {	
		Calendar instance = Calendar.getInstance();

		instance.set(Calendar.DAY_OF_MONTH, -1);

		instance.set(Calendar.HOUR_OF_DAY, 23);
		instance.set(Calendar.MINUTE, 59);
		instance.set(Calendar.SECOND, 59);
		instance.set(Calendar.MILLISECOND, 99);
		instance.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);

		instance.set(Calendar.DAY_OF_MONTH, instance.get(Calendar.DAY_OF_MONTH)-7);
		/*
	instance.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		 */
		return instance.getTime() ;

	}
	/**
	 * 
	 * Método para somar ou subtrair dias a partir de uma data.
	 * 
	 * @param dataCorrente Date
	 * @param quantidadeDeDias Integer
	 * @return Date
	 * 
	 * @author and
	 */
	public static Date somaOuSubtraiDias(Date dataCorrente, Integer quantidadeDeDias) {	
		Calendar instance = Calendar.getInstance();
		instance.setTime(dataCorrente);
		instance.add(Calendar.DAY_OF_WEEK, quantidadeDeDias);
		return instance.getTime() ;
	}
	
	
	/**
	 * 
	 * Verifica se a data passada por parâmetro é o último dia do mês
	 * 
	 * @param dia
	 * @return True ou False 
	 * 
	 * @author Walter Fontes
	 */
	public static Boolean isUltimoDiaMes(Date dia) {
		
		if (dia == null) return Boolean.FALSE;
		
		Calendar instance = Calendar.getInstance();
		instance.setTime(dia);
		instance.add(Calendar.DATE, 1);
		
		if (instance.get(Calendar.DATE) == 1) {
			return Boolean.TRUE;
		}
		
		return Boolean.FALSE;
	}

	/**
	 * Obtem data com segundo e milesegundo zerado
	 * @param date
	 * @return
	 */
	public static Date getDateMinuto() {
		
		Calendar instance = Calendar.getInstance();
		
		instance.set(Calendar.SECOND, 0);
		instance.set(Calendar.MILLISECOND, 0);


		return instance.getTime();
	}	
	
}